/*
 * @Description: 角色信息
 * @Author: DHL
 * @Date: 2022-03-30 13:50:53
 * @LastEditors: DHL
 * @LastEditTime: 2022-11-23 08:56:08
 */

import { defineComponent, computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { ElMessage, ElMessageBox, TabPaneName } from 'element-plus'
import { assign, cloneDeep } from 'lodash-es'
import {
  arraySerializeToStr,
  getElementHeight,
  getTreeCheckKeys,
  listToTree
} from '/@/utils/twUtils'
import { usePermission } from '/@/hooks/web/permission'
import { RoleModel } from '/@/api/system/model/roleModel'
import {
  apiRoleDeleteRoleUser,
  apiRoleLogicBatchDeleteByIds,
  apiRoleSaveRoleAccreditResource,
  apiRoleSaveRoleResource,
  apiRoleSearch,
  apiRoleDataScope,
  apiRoleSearchListRoleDataScopes
} from '/@/api/system/role'
import type Node from 'element-plus/es/components/tree/src/model/node'
import { stringUtils } from '/@/utils/stringUtils'
import { ProjectListResultModel, ProjectModel } from '/@/api/system/model/projectModel'
import { apiProjectList } from '/@/api/system/project'
import {
  apiResourceSearchAuthResourceTree,
  apiResourceSearchRoleAccreditResourceTree
} from '/@/api/system/resource'
import { ResourceModel } from '/@/api/system/model/resourceModel'
import { UserPageParams, UserModel } from '/@/api/system/model/userModel'
import { apiUserSearchRoleUsers } from '/@/api/system/user'

import roleForm from './form.vue'
import organizationTree from '../../components/organizationTree.vue'
import roleSelectUser from './roleSelectUser.vue'
import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'

import { apiOrganizationSearchTree } from '/@/api/system/organization'
import { OrganizationModel } from '/@/api/system/model/organizationModel'

export default defineComponent({
  name: 'Role',
  components: { roleForm, organizationTree, roleSelectUser, Splitpanes, Pane },
  setup(props) {
    //////////////////////////////////////////////////
    // 属性
    //////////////////////////////////////////////////

    const loading = ref(false)

    // 权限控制
    const { hasPermission } = usePermission()

    /**
     * 表格数据
     */
    const tableData = ref()

    /**
     * 查询表单
     */
    const searchFormRef = ref()

    /**
     * 数据列表
     */
    const tableRef = ref()

    /**
     * 表单
     */
    const formRef = ref()

    /**
     * 选择的角色
     */
    const selectRole = ref()

    //////////////////////////////////////////////////
    // 查询表单
    //////////////////////////////////////////////////

    const defaultSearchForm = {
      isAllChildNode: false,
      queryLikeStr: ''
    }

    /**
     * 查询表单
     */
    const searchForm = reactive(cloneDeep(defaultSearchForm))

    //////////////////////////////////////////////////
    // 表格
    //////////////////////////////////////////////////

    //////////////////////////////////////////////////
    // 函数
    //////////////////////////////////////////////////

    /**
     * 查询表格数据函数
     * @param queryParams
     */
    function searchList() {
      loading.value = true
      apiRoleSearch(
        assign(searchForm, {
          orgId: selectOrg.id
        })
      )
        .then((result) => {
          if (result?.success) {
            tableData.value = result.data
          }
        })
        .catch(() => {})
        .finally(() => {
          loading.value = false
        })
    }

    /**
     * 重置
     */
    function handleReset() {
      assign(searchForm, cloneDeep(defaultSearchForm))
      tableRef.value.handleQuery()
    }

    /**
     * 批量删除
     */
    function handleDelete(row?: RoleModel) {
      let selectRows: Array<RoleModel> = []

      if (row) {
        selectRows = [row]
      } else {
        selectRows = tableRef.value.getSelectRows()
      }

      if (selectRows.length === 0) {
        ElMessage.warning('请选择需要删除的数据')
        return
      }

      ElMessageBox.confirm(`此操作将删除${selectRows.length}条记录, 是否继续?`, '删除提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          loading.value = true
          const ids = arraySerializeToStr(selectRows, 'id')
          apiRoleLogicBatchDeleteByIds(ids)
            .then((result) => {
              if (result?.success) {
                searchList()
                ElMessage.success(result.message)
              } else {
                ElMessage.error(result?.message)
              }
            })
            .catch(() => {})
            .finally(() => {
              loading.value = false
            })
        })
        .catch(() => {
          ElMessage.info('删除被取消了')
        })
    }

    /**
     * 弹出表单
     */
    function handleOpenForm(action: string, row?: RoleModel) {
      // if (stringUtils.isEmpty(selectOrg.id)) {
      //   ElMessage.warning('请选择机构')
      //   return
      // }

      formRef.value.handleOpen(action, row, {
        orgId: selectOrg.id,
        orgName: orgTreeRef.value.getSelectNodeParentName().join(' - ')
      })
    }

    /**
     * 选择角色
     */
    function handleRoleClick(row: RoleModel) {
      selectRole.value = row
      nextTick(() => {
        handleSearchAuthResourceTree()
        handleSearchAccreditResourceTree()
        handleSearchUserTable()

        // 数据权限
        handleSearchDataScopeOrgTree()
        handleSearchRoleDataScopes()
        Object.assign(dataScope, {
          dataScopeType: row.dataScopeType,
          defaultCheckedKeys: row.dataScopeIds
        })
      })
    }

    //////////////////////////////////////////////////
    // 机构树
    //////////////////////////////////////////////////
    const orgTreeRef = ref()

    /**
     * 选中的组织机构
     */
    let selectOrg: any = {}

    /**
     * 节点点击事件
     */
    function handleNodeClick(treeNode?: Node) {
      selectOrg = treeNode ? treeNode : {}
      searchList()
    }

    //////////////////////////////////////////////////
    // 项目信息
    //////////////////////////////////////////////////
    /**
     * 项目列表
     */
    const projectList = ref([] as Array<ProjectModel>)

    /**
     * 查询项目列表
     */
    function handleSearchProjectList() {
      apiProjectList({}).then((result: ProjectListResultModel) => {
        if (result?.success && result.data) {
          projectList.value = result.data

          if (projectList.value && projectList.value.length > 0) {
            handleResource.projectId = `${projectList.value[0].id}`
            accreditResource.projectId = `${projectList.value[0].id}`
          }
        }
      })
    }

    //////////////////////////////////////////////////
    // 经办权限
    //////////////////////////////////////////////////

    const handleTreeRef = ref()

    /**
     * 经办权限
     */
    const handleResource = reactive({
      projectId: '',
      keyWord: '',
      loading: false,
      treeData: [] as Array<ResourceModel>,
      defaultExpandedKeys: [] as Array<string>,
      defaultCheckedKeys: [] as Array<string>,
      treeProps: {
        label: 'name',
        children: 'children',
        disabled: 'false'
      }
    })

    watch(
      () => handleResource.keyWord,
      (val: string) => {
        handleTreeRef.value!.filter(val)
      }
    )

    /**
     * 经办权限关键字过滤
     * @param value
     * @param data
     * @returns
     */
    function handleFilterTree(value: string, data: any) {
      if (!value) return true
      return data.name.includes(value)
    }

    /**
     * tree展开折叠
     */
    function handleExpandTree(isExpand: boolean) {
      handleTreeRef.value.store._getAllNodes().forEach((item: { expanded: boolean }) => {
        item.expanded = isExpand
      })
    }

    /**
     * 查询经办权限
     */
    function handleSearchAuthResourceTree() {
      handleResource.loading = true
      apiResourceSearchAuthResourceTree({
        type: 1,
        bizId: selectRole.value.id,
        projectId: handleResource.projectId
      })
        .then((result) => {
          if (result?.success) {
            handleResource.treeData = listToTree(
              result.data,
              'id',
              'parentResId',
              ''
            ) as Array<ResourceModel>

            // 默认展开第一层节点
            handleResource.defaultExpandedKeys = []
            for (const node of handleResource.treeData) {
              handleResource.defaultExpandedKeys.push(node.id)
            }

            // 已授权的节点
            handleResource.defaultCheckedKeys = []
            getTreeCheckKeys(
              handleResource.treeData,
              'id',
              'parentResId',
              '',
              handleResource.defaultCheckedKeys
            )

            nextTick(() => {
              handleTreeRef.value.setCheckedKeys(handleResource.defaultCheckedKeys)
            })
          } else {
            ElMessage.error(result?.message)
          }
        })
        .finally(() => {
          handleResource.loading = false
        })
    }

    /**
     * 经办权限授权
     */
    function handleGrant() {
      const keys = handleTreeRef.value.getCheckedKeys()

      handleResource.loading = true

      apiRoleSaveRoleResource({
        roleId: selectRole.value.id,
        resIds: keys.join(','),
        projectId: handleResource.projectId
      })
        .then((result) => {
          if (result?.success) {
            ElMessage.success(result.message)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .finally(() => {
          handleResource.loading = false
        })
    }

    //////////////////////////////////////////////////
    // 授权权限
    //////////////////////////////////////////////////

    const accreditTreeRef = ref()

    /**
     * 授权权限
     */
    const accreditResource = reactive({
      projectId: '',
      keyWord: '',
      loading: false,
      treeData: [] as Array<ResourceModel>,
      defaultExpandedKeys: [] as Array<string>,
      defaultCheckedKeys: [] as Array<string>,
      treeProps: {
        label: 'name',
        children: 'children',
        disabled: 'false'
      }
    })

    watch(
      () => accreditResource.keyWord,
      (val: string) => {
        accreditTreeRef.value!.filter(val)
      }
    )

    /**
     * 授权权限关键字过滤
     * @param value
     * @param data
     * @returns
     */
    function accreditFilterTree(value: string, data: any) {
      if (!value) return true
      return data.name.includes(value)
    }

    /**
     * 授权tree展开折叠
     */
    function accreditExpandTree(isExpand: boolean) {
      accreditTreeRef.value.store._getAllNodes().forEach((item: { expanded: boolean }) => {
        item.expanded = isExpand
      })
    }

    /**
     * 查询授权权限
     */
    function handleSearchAccreditResourceTree() {
      accreditResource.loading = true
      apiResourceSearchRoleAccreditResourceTree({
        roleId: selectRole.value.id,
        projectId: accreditResource.projectId
      })
        .then((result) => {
          if (result?.success) {
            accreditResource.treeData = listToTree(
              result.data,
              'id',
              'parentResId',
              ''
            ) as Array<ResourceModel>

            // 默认展开第一层节点
            accreditResource.defaultExpandedKeys = []
            for (const node of accreditResource.treeData) {
              accreditResource.defaultExpandedKeys.push(node.id)
            }

            // 已授权的节点
            accreditResource.defaultCheckedKeys = []
            getTreeCheckKeys(
              accreditResource.treeData,
              'id',
              'parentResId',
              '',
              accreditResource.defaultCheckedKeys
            )

            nextTick(() => {
              accreditTreeRef.value.setCheckedKeys(accreditResource.defaultCheckedKeys)
            })
          } else {
            ElMessage.error(result?.message)
          }
        })
        .finally(() => {
          accreditResource.loading = false
        })
    }

    /**
     * 授权权限授权
     */
    function handleAccreditGrant() {
      const keys = accreditTreeRef.value.getCheckedKeys()

      accreditResource.loading = true

      apiRoleSaveRoleAccreditResource({
        roleId: selectRole.value.id,
        resIds: keys.join(','),
        projectId: accreditResource.projectId
      })
        .then((result) => {
          if (result?.success) {
            ElMessage.success(result.message)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .finally(() => {
          accreditResource.loading = false
        })
    }

    //////////////////////////////////////////////////
    // 角色用户
    //////////////////////////////////////////////////
    const userToolBarRef = ref()
    const userTableRef = ref()

    /**
     * 角色用户
     */
    const roleUser = reactive({
      loading: false,
      loadingByDel: false,
      searchForm: {
        loginName: '',
        name: '',
        status: '1'
      },
      userTableStyle: {
        height: '95%'
      },
      tableData: [] as any,
      tableOptions: {
        id: 'roleUserTable',
        autoLoad: false,
        sortConfig: {
          defaultSort: [{ field: 'loginName', order: 'asc' }]
        },
        columns: [
          { type: 'checkbox', fixed: 'left', title: '', width: 40 },
          { type: 'seq', fixed: 'left', title: '序号', width: 50 },
          { field: 'loginName', title: '登陆名称', sortable: true },
          { field: 'name', title: '姓名', sortable: true },
          {
            field: 'status',
            title: '用户状态',
            sortable: true,
            params: { dict: 'USER_STATUS' }
          },
          { field: 'userType', title: '用户类型', sortable: true, params: { dict: 'USERTYPE' } },
          { field: 'position', title: '职务', sortable: true },
          { field: 'phone', title: '手机号码', sortable: false },
          { title: '操作', fixed: 'right', width: 80, slots: { default: 'userTableAction' } }
        ]
      }
    })

    /**
     * 查询用户数据
     */
    function searchUserList(queryParams: UserPageParams) {
      roleUser.loading = true
      const searchParams = assign(queryParams, roleUser.searchForm, {
        roleId: selectRole.value.id
      })
      apiUserSearchRoleUsers(searchParams)
        .then((result) => {
          roleUser.tableData = result
        })
        .finally(() => {
          roleUser.loading = false
        })
    }

    /**
     * 刷新用户列表
     */
    function handleSearchUserTable() {
      userTableRef.value.handleQuery()
    }

    /**
     * 是否有选中的行
     */
    const isSelectUserRows = computed(() => {
      let selectRows: Array<UserModel> = []
      if (userTableRef.value) {
        selectRows = userTableRef.value.getSelectRows()
      }
      return selectRows.length < 1
    })

    /**
     * 删除角色用户
     */
    function handleDeleteRoleUser(row?: UserModel) {
      let selectRows: Array<UserModel> = []
      if (row) {
        selectRows.push(row)
      } else {
        selectRows = userTableRef.value.getSelectRows()
      }

      roleUser.loading = true
      roleUser.loadingByDel = true
      const userIds = arraySerializeToStr(selectRows, 'id')
      apiRoleDeleteRoleUser({
        roleId: selectRole.value.id,
        userIds: userIds
      })
        .then((result) => {
          if (result?.success) {
            ElMessage.success(result.message)
            handleSearchUserTable()
          } else {
            ElMessage.error(result?.message)
          }
        })
        .finally(() => {
          roleUser.loading = false
          roleUser.loadingByDel = false
        })
    }

    //////////////////////////////////////////////////
    // 选择用户
    //////////////////////////////////////////////////
    const roleSelectUserRef = ref()

    /**
     * 弹出选择用户
     */
    function handleShowSelectUser() {
      const role = cloneDeep(selectRole.value)
      assign(role, { orgName: orgTreeRef.value.getParentName(role.orgId) })
      roleSelectUserRef.value.handleOpen(role)
    }

    //////////////////////////////////////////////////
    // tabs
    //////////////////////////////////////////////////
    /**
     * 页签改变事件
     * @param targetName
     */
    function handleTabChange(targetName: TabPaneName) {
      if (targetName === 'roleUser') {
        nextTick(() => {
          roleUser.userTableStyle.height = `calc(100% - ${getElementHeight(
            userToolBarRef.value
          )}px)`
        })
      }
    }

    //////////////////////////////////////////////////
    // 数据权限
    //////////////////////////////////////////////////

    /**
     *
     * 角色数据权限
     */
    const dataScope = reactive({
      loading: false,
      keyWord: '',
      dataScopeType: '', // 数据权限类型（1：全部数据；2：本部门及以下数据；3：本部门数据；4：仅本人数据；5：自定义数据）
      orgTreeData: [] as Array<OrganizationModel>, // 机构数据
      defaultExpandedKeys: [] as Array<string>,
      defaultCheckedKeys: [] as Array<string>,
      treeProps: {
        label: 'name',
        children: 'children',
        disabled: 'false'
      }
    })

    const dataScopeOrgsTreeRef = ref()

    /**
     * 查询机构
     */
    function handleSearchDataScopeOrgTree() {
      apiOrganizationSearchTree().then((result) => {
        if (result?.success) {
          dataScope.orgTreeData = listToTree(
            result?.data ? result.data : [],
            'id',
            'parentOrgId',
            ''
          )
        }
      })
    }

    watch(
      () => dataScope.keyWord,
      (val: string) => {
        dataScopeOrgsTreeRef.value!.filter(val)
      }
    )

    /**
     * 授权权限关键字过滤
     * @param value
     * @param data
     * @returns
     */
    function dataScopeOrgsFilterTree(value: string, data: any) {
      if (!value) return true
      return data.name.includes(value)
    }

    /**
     * 授权tree展开折叠
     */
    function dataScopeOrgsExpandTree(isExpand: boolean) {
      dataScopeOrgsTreeRef.value.store._getAllNodes().forEach((item: { expanded: boolean }) => {
        item.expanded = isExpand
      })
    }

    /**
     * 提交数据权限
     */
    function handleSubmitDataScope() {
      dataScope.loading = true

      let keys: Array<string> = []
      if (dataScope.dataScopeType === '7') {
        keys = dataScopeOrgsTreeRef.value.getCheckedKeys()
      }

      apiRoleDataScope({
        id: selectRole.value.id,
        dataScopeType: dataScope.dataScopeType,
        dataScopeIds: keys
      })
        .then((result) => {
          if (result?.success) {
            ElMessage.success(result.message)
          } else {
            ElMessage.error(result?.message)
          }
        })
        .finally(() => {
          dataScope.loading = false
        })
    }

    /**
     * 根据角色ID查询自定义数据权限
     */
    function handleSearchRoleDataScopes() {
      apiRoleSearchListRoleDataScopes(selectRole.value.id).then((result) => {
        if (result?.success) {
          dataScope.defaultExpandedKeys = result.data
          dataScope.defaultCheckedKeys = result.data
        }
      })
    }

    //////////////////////////////////////////////////
    // 生命周期
    //////////////////////////////////////////////////
    onMounted(() => {
      searchList()
      handleSearchProjectList()
    })

    return {
      loading,
      tableData,
      searchFormRef,
      tableRef,
      formRef,
      searchForm,
      orgTreeRef,
      projectList,
      handleResource,
      handleTreeRef,
      selectRole,
      searchList,
      handleReset,
      handleDelete,
      handleOpenForm,
      handleNodeClick,
      handleRoleClick,
      handleSearchAuthResourceTree,
      handleFilterTree,
      handleExpandTree,
      handleGrant,
      accreditTreeRef,
      accreditResource,
      accreditFilterTree,
      accreditExpandTree,
      handleSearchAccreditResourceTree,
      handleAccreditGrant,
      handleTabChange,
      userToolBarRef,
      userTableRef,
      roleUser,
      searchUserList,
      handleSearchUserTable,
      roleSelectUserRef,
      handleShowSelectUser,
      handleDeleteRoleUser,
      isSelectUserRows,
      dataScope,
      dataScopeOrgsTreeRef,
      dataScopeOrgsFilterTree,
      dataScopeOrgsExpandTree,
      handleSearchDataScopeOrgTree,
      handleSubmitDataScope
    }
  }
})
